package org.openkoala.koala.popup.javaclass.crud;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.openkoala.koala.deploy.curd.module.core.EntityModel;
import org.openkoala.koala.deploy.curd.module.core.FieldModel;
import org.openkoala.koala.deploy.curd.module.core.RelationType;
import org.openkoala.koala.deploy.curd.module.core.model.RelationFieldModel;
import org.openkoala.koala.deploy.curd.module.ui.Model;
import org.openkoala.koala.deploy.curd.module.ui.UIWidget;
import org.openkoala.koala.deploy.curd.module.ui.model.ViewModel;
import org.openkoala.koala.deploy.curd.module.ui.view.RelativeReadOnlyView;

/**
 * 
 * 类    名：CrudConfigurationComponent.java
 *   
 * 功能描述：CRUD配置的Component。	
 *  
 * 创建日期：2013-1-30上午10:53:30     
 * 
 * 版本信息：
 * 
 * 版权信息：Copyright (c) 2013 Koala All Rights Reserved
 * 
 * 作    者：xmfang(xinmin.fang@gmail.com)
 * 
 * 修改记录： 
 * 修 改 者    修改日期     文件版本   修改说明
 */
public class CrudConfigurationComponent extends CrudComponent {
    
	private Button add;
	private Button edit;
	private Button remove;
	
    private Composite parent;
    
    private Model model;
    private EntityModel entityModel;
    
    private TableViewer fieldTableViewer;
    
    private String modelType;
    
    CrudConfigurationComponent(Composite parent, Model model, EntityModel entityModel) {
        this.parent = parent;
        this.model = model;
        this.entityModel = entityModel;
        this.modelType = CrudUtils.getModelType(model);
    }
    
    public Control createControl() {
    	GridData gridData = null;
    	if (model instanceof ViewModel) {
    		gridData = new GridData(GridData.FILL_HORIZONTAL);
            gridData.heightHint = 230;
    	} else {
    		gridData = new GridData(GridData.FILL_BOTH);
    	}
        
        GridLayout gridLayout = new GridLayout(2, false);
        
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setLayoutData(gridData);
        composite.setLayout(gridLayout);
        
        generateTableComposite(composite);
        generateOperationComposite(composite);
        
        return composite;
    }

    private void generateTableComposite(Composite parent) {
        GridLayout gridLayout = new GridLayout(1, false);
        GridData gridData = new GridData(GridData.FILL_VERTICAL);
        gridData.widthHint = 400;
        
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setLayout(gridLayout);
        composite.setLayoutData(gridData);
        
        fieldTableViewer = new TableViewer(composite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.FULL_SELECTION);
        
        GridData tableGridData = new GridData(GridData.FILL_BOTH);
        final Table table = fieldTableViewer.getTable();
        table.setLayoutData(tableGridData);
        initTable(table);
        
        fieldTableViewer.setContentProvider(new FieldTableContentProvider(model));
        fieldTableViewer.setLabelProvider(new FieldTableLabelProvider());
        fieldTableViewer.setInput(new Object());
        fieldTableViewer.addSelectionChangedListener(new TableSelectionListener());
        fieldTableViewer.addDoubleClickListener(new TableDoubleClickListener());
    }
    
    private void initTable(final Table table) {
        table.setHeaderVisible(true);
        table.setLinesVisible(true);
        
        List<String> columnNames = new ArrayList<String>();
        columnNames.add("属性名");
        columnNames.add("显示名称");
        
        if (modelType.equals(CrudConstants.MODEL_EDIT)) {
        	columnNames.add("编辑类型");
        } else if (modelType.equals(CrudConstants.MODEL_VIEW)) {
        	columnNames.add("关联属性");
        }
        addTableColumns(table, columnNames);
    }
    
    private void addTableColumns(final Table table, final List<String> columnNames) {
        int[] columnWidths = new int[] {
                120, 120, 130
        };

        for (int i = 0; i < columnNames.size(); i ++) {
            TableColumn tableColumn = new TableColumn(table, SWT.NONE);
            tableColumn.setText(columnNames.get(i));
            tableColumn.setWidth(columnWidths[i]);
        }
    }
    
    private void generateOperationComposite(Composite parent) {
        GridLayout gridLayout = new GridLayout(1, false);
        GridData gridData = new GridData(GridData.FILL_BOTH);
        
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setLayout(gridLayout);
        composite.setLayoutData(gridData);
        
        GridData buttonGridDate = new GridData(GridData.FILL_HORIZONTAL);
        
        add = new Button(composite, SWT.PUSH);
        add.setText("添加");
        add.setData(CrudConstants.BUTTON_ADD);
        add.setLayoutData(buttonGridDate);
        add.addSelectionListener(new ButtonSelectionListener());
        
        edit = new Button(composite, SWT.PUSH);
        edit.setText("编辑");
        edit.setData(CrudConstants.BUTTON_EDIT);
        edit.setLayoutData(buttonGridDate);
        edit.setEnabled(false);
        edit.addSelectionListener(new ButtonSelectionListener());
        
        remove = new Button(composite, SWT.PUSH);
        remove.setText("删除");
        remove.setData(CrudConstants.BUTTON_REMOVE);
        remove.setLayoutData(buttonGridDate);
        remove.setEnabled(false);
        remove.addSelectionListener(new ButtonSelectionListener());
    }

	@Override
	public void addItem(UIWidget widget) {
    	fieldTableViewer.add(widget);
	}

	@Override
	public void update(UIWidget oldWidget, UIWidget newWidget) {
		fieldTableViewer.remove(oldWidget);
    	fieldTableViewer.add(newWidget);
	}

	@Override
	public void refresh(UIWidget widget) {
    	fieldTableViewer.refresh(widget);
	}
   
    /**
     * 按钮监听器
     * 版权信息：Copyright (c) 2013 Koala All Rights Reserved
     * 作    者：xmfang(xinmin.fang@gmail.com)
     */
    private class ButtonSelectionListener implements SelectionListener {

		@Override
		public void widgetDefaultSelected(SelectionEvent e) {
		}

		@Override
		public void widgetSelected(SelectionEvent event) {
			Button button = (Button) event.getSource();
			int selectedIndex = fieldTableViewer.getTable().getSelectionIndex();
            
        	if (button.getData().equals(CrudConstants.BUTTON_ADD)) {
        		responseAddButton();
				return;
			}
        	
            UIWidget widget = (UIWidget) fieldTableViewer.getElementAt(selectedIndex);
			if (button.getData().equals(CrudConstants.BUTTON_EDIT)) {
				responseEditButton(widget);
				return;
			}
			
			if (button.getData().equals(CrudConstants.BUTTON_REMOVE)){
				responseRemoveButton(widget);
			}
		}
    }

	private void responseAddButton() {
		List<FieldModel> fieldModels = new ArrayList<FieldModel>(entityModel.getFields());
		fieldModels.removeAll(entityModel.getObjectValueFieldModel());
		fieldModels.removeAll(entityModel.getIDFieldModel());
		if (CrudConstants.MODEL_EDIT.equals(modelType)) {
			fieldModels.removeAll(entityModel.getRelationFieldModel());
		} else {
			for (RelationFieldModel relationFieldModel : entityModel.getRelationFieldModel()) {
				RelationType relationType = CrudUtils.getRelationTypeByModel(relationFieldModel.getRelationModel());
				if (relationType != RelationType.ManyToOne && relationType != RelationType.OneToOne) {
					fieldModels.remove(relationFieldModel);
				}
			}
		}
		
		List<FieldModel> fieldModelsToAdd = new ArrayList<FieldModel>();
		for (FieldModel fieldModel : fieldModels) {
			if (!CrudUtils.fieldNameIsInModel(fieldModel.getName(), model)) {
				fieldModelsToAdd.add(fieldModel);
			}
		}
		
		if (fieldModelsToAdd.isEmpty()) {
			MessageDialog.openInformation(parent.getShell(), "提示", "没有可添加的属性");
			return;
		}
		
		EditFieldConfigurationDialog dialog = EditFieldConfigurationDialog.createByAddField(parent.getShell(), this, fieldModelsToAdd, model);
		dialog.open();
	}
	
	private void responseEditButton(UIWidget widget) {
		if (widget instanceof RelativeReadOnlyView) {
			EditFieldConfigurationDialog dialog = 
					EditFieldConfigurationDialog.createByUpdateAssociationField(parent.getShell(), this, 
							widget, model, createAssociationFieldModels((RelativeReadOnlyView) widget));
			dialog.open();
			return;
		}
		
		EditFieldConfigurationDialog dialog = EditFieldConfigurationDialog.createByUpdateField(parent.getShell(), this, widget, model);
		dialog.open();
	}
	
	private void responseRemoveButton(UIWidget widget) {
		fieldTableViewer.remove(widget);
		model.getViews().remove(widget);
	}
	
	private List<FieldModel> createAssociationFieldModels(RelativeReadOnlyView relativeReadOnlyView) {
		List<FieldModel> results = new ArrayList<FieldModel>();
		
		RelationFieldModel relationFieldModel = 
				(RelationFieldModel) CrudUtils.getFieldModelByName(relativeReadOnlyView.getRelative(), entityModel.getFields());
		EntityModel associationEntityModel = relationFieldModel.getRelationModel().getEntityModel();
		List<FieldModel> fieldModels = new ArrayList<FieldModel>(associationEntityModel.getFields());
		fieldModels.remove(associationEntityModel.getObjectValueFieldModel());
		fieldModels.remove(associationEntityModel.getRelationFieldModel());
		
		for (FieldModel fieldModel : fieldModels) {
			results.add(fieldModel);
		}
		return results;
	}
    
    /**
     * 表格行选择监听器。	
     * 版权信息：Copyright (c) 2013 Koala All Rights Reserved
     * 作    者：xmfang(xinmin.fang@gmail.com)
     */
    private class TableSelectionListener implements ISelectionChangedListener {
		@Override
		public void selectionChanged(SelectionChangedEvent event) {
			edit.setEnabled(true);
			remove.setEnabled(true);
		}
    }
    
    private class TableDoubleClickListener implements IDoubleClickListener {
		@Override
		public void doubleClick(DoubleClickEvent event) {
			int selectedIndex = fieldTableViewer.getTable().getSelectionIndex();
			UIWidget widget = (UIWidget) fieldTableViewer.getElementAt(selectedIndex);
			responseEditButton(widget);
		}
    }
    
}
